import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react'
import type { ReactNode } from 'react'
import { message } from 'antd'
import { authApi } from '@api/auth'
import type { AuthUser, LoginPayload, LoginResponse } from '@/types/auth'
import { storage } from '@utils/storage'

type AuthContextValue = {
  user: AuthUser | null
  loading: boolean
  login: (payload: LoginPayload) => Promise<LoginResponse>
  logout: (options?: { silent?: boolean }) => void
}

const AuthContext = createContext<AuthContextValue | undefined>(undefined)

type AuthProviderProps = {
  children: ReactNode
}

const TOKEN_STORAGE_KEY = 'erai_token'

export const AuthProvider = ({ children }: AuthProviderProps) => {
  const [user, setUser] = useState<AuthUser | null>(null)
  const [loading, setLoading] = useState(true)

  const logout = useCallback((options?: { silent?: boolean }) => {
    storage.remove(TOKEN_STORAGE_KEY)
    setUser(null)
    if (!options?.silent) {
      message.success('已退出登录')
    }
  }, [])

  const handleBootstrap = useCallback(async () => {
    const token = storage.get<string | null>(TOKEN_STORAGE_KEY)
    if (!token) {
      setLoading(false)
      return
    }

    try {
      const profile = await authApi.getProfile()
      setUser(profile.user)
    } catch {
      logout({ silent: true })
    } finally {
      setLoading(false)
    }
  }, [logout])

  useEffect(() => {
    void handleBootstrap()
  }, [handleBootstrap])

  const login = useCallback(async (payload: LoginPayload) => {
    const result = await authApi.login(payload)

    storage.set(TOKEN_STORAGE_KEY, result.token)
    setUser(result.user)
    message.success(`欢迎回来，${result.user.name}`)

    return result
  }, [])

  const value = useMemo<AuthContextValue>(
    () => ({
      user,
      loading,
      login,
      logout,
    }),
    [user, loading, login, logout],
  )

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}

export const useAuth = () => {
  const context = useContext(AuthContext)
  if (!context) {
    throw new Error('useAuth 必须在 AuthProvider 内使用')
  }
  return context
}


